#ifndef HASHMANGER_H
#define HASHMANGER_H

#include <QObject>
#include <bitset>
#include <Chess.h>
#include <set>
#include <mutex>
#include <map>
#include <QDebug>
#include <fstream>
#include <memory>

static const int MB = 1024*1024;
class HashManger : public QObject
{
    Q_OBJECT
public:
    explicit HashManger(QObject *parent = nullptr);
    static const int NOT_FIND = UNTOUCH;
    Score_struct find_score(Cb_with_num &cb);
    void update(Cb_with_num &cb,Score_struct &s);
    bool is_finished();
    volatile static double i,shot;
    void load_future(char complete_chess_num,char depth);
    void load_current(char complete_chess_num,char depth);
    void reset_hash();
private:
    std::mutex load_lock;
    bool if_update = true,is_updating = false;
    long max_save_size = 400*MB,max_load_size = 400*MB;  // 21M = 60W张棋盘
    int step_changed1 = 35,step_change2 = 55,second_load_size = 200*MB,thrid_load_size = 100*MB;
    int update_num = 300000,append_num = 600000;
    const short unit_size = 27;
    class std::thread * load_thread[2];
    int get_load_size(char chess_num){
        if(chess_num < step_changed1) return max_load_size;
        else if(chess_num < step_change2)return second_load_size;
        else return thrid_load_size;
    }
    typedef  std::unordered_map<std::bitset<256>,Score_struct> Hash;
    struct Map_Set{
        Hash old_table;
        Hash new_table;
        Map_Set(){}
    };
    std::unordered_map<short,Map_Set> map_search;
    std::map<short,std::pair<double,double>> old_use_num;
    std::map<short,std::shared_ptr<std::mutex>> lock;
    //注意以下评估值全为黑方为当前玩家时的值
    std::string num_save_path = "C:\\AAAAA\\chess_borad_data\\step_num";
    std::string save_path = "C:\\AAAAA\\chess_borad_data\\save_step";    //哈希值存储路径
    std::set<short> now_cb;
    std::map<short,bool> load_finished;
    void init_hash();
    void save(int chess_num);
    void load(int chess_num,bool will_del = true);
    void outfile(std::ofstream &out,const std::bitset<256> &key,const Score_struct &value);
    void infile(std::ifstream &in,std::bitset<256> &key,Score_struct &value);
    std::bitset<256> turn_to_key(int * cb);
    std::string make_table_path(int chess_num) const;
signals:
};

#endif // HASHMANGER_H
